package com.info33.platform.system.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.codec.Base64;
import cn.hutool.core.util.IdcardUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.huaweicloud.sdk.ocr.v1.model.IdCardResult;
import com.info33.platform.business.app.dto.AppUpdateDTO;
import com.info33.platform.business.app.vo.AppCenterVO;
import com.info33.platform.common.constant.TableConstant;
import com.info33.platform.common.enums.StatusEnum;
import com.info33.platform.common.exception.NoCertificationException;
import com.info33.platform.common.exception.TransactionalException;
import com.info33.platform.common.huawei.HuaWeiApi;
import com.info33.platform.common.mvc.vo.Result;
import com.info33.platform.common.util.SysUtil;
import com.info33.platform.doc.entity.DocFileDetail;
import com.info33.platform.doc.service.DocFileService;
import com.info33.platform.system.dao.SysUserDao;
import com.info33.platform.system.dao.SysUserProfileDao;
import com.info33.platform.system.dto.SysUserProfileDTO;
import com.info33.platform.system.entity.SysUser;
import com.info33.platform.system.entity.SysUserEducation;
import com.info33.platform.system.entity.SysUserProfile;
import com.info33.platform.system.service.SysUserEducationService;
import com.info33.platform.system.service.SysUserProfileService;
import com.info33.platform.system.vo.SysUserVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.List;
import java.util.UUID;

/**
 * @author admin
 */
@Service
public class SysUserProfileServiceImpl extends ServiceImpl<SysUserProfileDao, SysUserProfile> implements SysUserProfileService {

    @Autowired
    private SysUserDao sysUserDao;
    @Autowired
    private SysUserProfileDao sysUserProfileDao;
    @Autowired
    private DocFileService docFileService;
    @Autowired
    private SysUserEducationService sysUserEducationService;

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public SysUserProfile register(SysUserProfileDTO dto, Long tid, Long uid) {
        // 校验用户拓展信息
        SysUserProfile profile = sysUserProfileDao.selectOne(new QueryWrapper<SysUserProfile>()
                .eq("user_id", uid)
                .eq(TableConstant.TENANT_ID, tid)
                .last(TableConstant.LIMIT_ONE));
        // 是否有旧信息？
        if (!ObjectUtils.isEmpty(profile)) {
            if (!ObjectUtils.isEmpty(dto)){
                BeanUtil.copyProperties(dto,profile,CopyOptions.create().setIgnoreNullValue(true));
            }
            if (sysUserProfileDao.updateById(profile) != 1) {
                throw new TransactionalException();
            }
            return profile;
        }
        // 新用户拓展信息 START
        profile = new SysUserProfile();
        if (!ObjectUtils.isEmpty(dto)){
            BeanUtils.copyProperties(dto, profile);
        }
        profile.setUserId(uid);
        profile.setNickName(ObjectUtils.isEmpty(profile.getNickName())
                ? "游客" + UUID.randomUUID().toString().replace("-", "").substring(0, 10)
                : profile.getNickName());
        profile.setTrueName(ObjectUtils.isEmpty(profile.getTrueName())
                ? profile.getNickName()
                : profile.getTrueName());
        if (sysUserProfileDao.insert(profile) != 1) {
            throw new TransactionalException();
        }
        return profile;
    }

    @Override
    public Result<Object> appCertification(SysUserVO currentUser, MultipartFile[] multipartFiles) {
        // 用户基本信息
        SysUser appUser = new SysUser();
        appUser.setId(currentUser.getId());
        // 用户拓展信息
        SysUserProfile userProfile = new SysUserProfile();

        byte[] bytes;
        try {
            bytes = multipartFiles[0].getBytes();
        } catch (IOException e) {
            e.printStackTrace();
            return Result.error("身份证上传失败，请重试");
        }
        // 先保存身份证图片，避免其它操作失败，多次调用华为云 api
        Result<List<DocFileDetail>> result = docFileService.businessUpload(multipartFiles, "sensitivity", currentUser.getTenant().getId());
        if (StatusEnum.SUCCESS.getCode() != result.getCode()) {
            return Result.error(result.getMessage());
        }
        List<DocFileDetail> idCards = result.getData();
        userProfile.setIdCardBack(idCards.get(0).getNewName());
        userProfile.setIdCardFront(idCards.get(1).getNewName());

        // 调用华为云，获取身份证信息
        IdCardResult idCardResult = HuaWeiApi.idCardWithImage(Base64.encode(bytes));
        // 相关信息入库
        userProfile.setTrueName(idCardResult.getName());
        userProfile.setIdCard(idCardResult.getNumber());
        userProfile.setNation(idCardResult.getEthnicity());
        if (sysUserProfileDao.update(userProfile, new QueryWrapper<SysUserProfile>().eq("user_id", appUser.getId())) != 1
                || sysUserDao.updateById(appUser) != 1) {
            throw new TransactionalException();
        }
        return Result.ok();
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public Result<Object> checkCertification(SysUserVO currentUser) {
        SysUserProfile entity = sysUserProfileDao.selectOne(new QueryWrapper<SysUserProfile>()
                .eq("user_id", currentUser.getId())
                .eq(TableConstant.TENANT_ID, currentUser.getTenant().getId())
                .last(TableConstant.LIMIT_ONE));
        if (ObjectUtils.isEmpty(entity)) {
            // 缺少数据，添加对应数据
            entity = new SysUserProfile();
            entity.setUserId(currentUser.getId());
            if (sysUserProfileDao.insert(entity) != 1) {
                throw new TransactionalException();
            }
            throw new NoCertificationException();
        }
        if (ObjectUtils.isEmpty(entity.getIdCard()) || Boolean.FALSE.equals(IdcardUtil.isValidCard(entity.getIdCard()))) {
            throw new NoCertificationException();
        }
        return Result.ok();
    }

    @Override
    public AppCenterVO appProfileEcho(SysUserVO currentUser) {
        return sysUserProfileDao.appProfileEcho(currentUser.getId(), currentUser.getTenant().getId());
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public Result<Object> appUpdate(AppUpdateDTO dto, SysUserVO currentUser) {
        SysUser user = dto.getSysUser();
        user.setId(currentUser.getId());
        if (!ObjectUtils.isEmpty(user)
                && sysUserDao.updateById(user) != 1) {
            return Result.error(Result.RESULT_ERROR_PUBLIC_MSG);
        }
        // 若修改了用户名
        if (StringUtils.hasText(user.getLoginName())
                && !ObjectUtils.isEmpty(sysUserDao.selectOne(new QueryWrapper<SysUser>()
                .select(TableConstant.ID)
                .eq("login_name", user.getLoginName())
                .ne(TableConstant.ID, currentUser.getId())
                .last(TableConstant.LIMIT_ONE)))) {
            return Result.error("登录名 " + user.getLoginName() + " 已经存在，请更换");
        }
        SysUserProfile profile = dto.getUserProfile();
        profile.setHeadImg(user.getHeadImg());
        profile.setTrueName(user.getTrueName());
        profile.setNickName(user.getNickName());
        if (!ObjectUtils.isEmpty(profile)
                && !this.update(profile, new QueryWrapper<SysUserProfile>()
                .eq("user_id", currentUser.getId())
                .eq(TableConstant.TENANT_ID, currentUser.getTenant().getId()))) {
            throw new TransactionalException();
        }
        List<SysUserEducation> userEducations = dto.getUserEducations();
        if (!ObjectUtils.isEmpty(userEducations)) {
            userEducations.forEach(l -> l.setUserId(currentUser.getId()));
            if (!sysUserEducationService.saveOrUpdateBatch(userEducations)) {
                throw new TransactionalException();
            }
        }
        return Result.ok();
    }

    @Override
    public Result<Object> pcChangeHeadImg(SysUserProfileDTO dto) {
        Long profileId = sysUserProfileDao.getIdByTenantUserId(SysUtil.getCurrentUser().getSysTenantUserVO().getId());
        SysUserProfile profile = new SysUserProfile();
        profile.setId(profileId);
        profile.setHeadImg(dto.getHeadImg());
        return sysUserProfileDao.updateById(profile) == 1 ?
                Result.ok() :
                Result.error();
    }

}